Adding support for .bzl file operations#1464
Conversation
There was a problem hiding this comment.
Code Review
This pull request extends the build tools to support editing .bzl files, enabling buildozer-style transformations on global variables. Key changes include updated label parsing for .bzl targets, improved global variable detection that excludes function-local assignments, and modifications to cmdAdd and cmdRemove. Feedback highlights critical logic errors in the new command handlers where variable-based rule checks were inverted and cmdRemove incorrectly used an addition function. Refactoring was also recommended to eliminate duplicated label parsing logic.
| // The cmdXXX functions implement the various commands. | ||
|
|
||
| func cmdAdd(opts *Options, env CmdEnvironment) (*build.File, error) { | ||
| if env.Rule != nil && env.Rule.Call != nil { |
There was a problem hiding this comment.
The condition env.Rule.Call != nil is incorrect for variable editing. According to the changes in expandTargets (lines 995-996), variable targets are represented by a dummy Rule where the Call field is nil. This check makes the logic for adding values to variables unreachable.
| if env.Rule != nil && env.Rule.Call != nil { | |
| if env.Rule != nil && env.Rule.Call == nil { |
References
- When modifying code, ensure that changes are consistent with previous behavior, especially if the previous behavior was intentional.
Signed-off-by: Vladimir Suvorov <suvorovv@google.com> Adding support for .bzl file operations Signed-off-by: Vladimir Suvorov <suvorovv@google.com> Adding support for .bzl file operations Signed-off-by: Vladimir Suvorov <suvorovv@google.com> Adding support for .bzl file operations Signed-off-by: Vladimir Suvorov <suvorovv@google.com> Fixing comments Signed-off-by: Vladimir Suvorov <suvorovv@google.com> Fixing comments Signed-off-by: Vladimir Suvorov <suvorovv@google.com> Fix tests Signed-off-by: Vladimir Suvorov <suvorovv@google.com>
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for editing global variables in .bzl files via buildozer. It includes updates to label resolution to handle .bzl files and refactors the Kind() method for more robust path extraction. Review feedback points out a risk of panics in existing commands due to the introduction of rules with nil call expressions and identifies limitations in the variable detection logic regarding tuple unpacking and loop variables.
| if as, ok := x.(*build.AssignExpr); ok { | ||
| if lhs, ok := as.LHS.(*build.Ident); ok { | ||
| vars[lhs.Name] = as | ||
| } | ||
| } |
There was a problem hiding this comment.
This implementation only detects global variables assigned via simple identifiers (e.g., VAR = ...). It will miss variables assigned via tuple unpacking (e.g., (A, B) = ...) or those defined as loop variables in top-level for statements. While this may be acceptable for common use cases, it is a limitation of the current variable detection logic.
There was a problem hiding this comment.
Yes — that's a real limitation. Intended. Added to README
Signed-off-by: Vladimir Suvorov <suvorovv@google.com>
183af1b to
bb44e4c
Compare
Signed-off-by: Vladimir Suvorov <suvorovv@google.com>
Signed-off-by: Vladimir Suvorov <suvorovv@google.com>
|
PTAL at the buildkite errors before we spend time reviewing this |
|
The previous fail was due to CI infra. Rerun is fine |
oreflow
left a comment
There was a problem hiding this comment.
The .bzl expansion support LGTM as long as you add some documentation for that targets may be specified as such, but for the variable modifications we would require a strong reason to step back on that nodes are accessed and modified via the "name" attribute, if you have a specific case in mind it might even be better to support said case better via native rules instead of variables.
There was a problem hiding this comment.
Do you happen to have some further reasoning / requirements for the variable support?
It has been an intentional decision for the buildtools to identify targets using the "name" attribute since it generally simplifies BUILD file management as well as large scale changes across the google monorepo.
Use of variables also generally tends to have poor effects on build health, are not really aligned with https://bazel.build/build/style-guide#prefer-damp-build-files-over-dry, and is something we generally discourage.
So it would be interesting to learn what the specific need is, from what I can tell patches would generally be part of a target with a name as well?
Additionally the change to support variables seems to add some non-insignificant complexity across many of the commands.
| buildozer 'copy testonly protolib' //pkg:py_protolib | ||
|
|
||
| # Set two attributes in the same rule | ||
| # Set two attributes in the same rule |
| bzlPart := rule[:idx+4] | ||
| rulePart = rule | ||
| if idx+4 < len(rule) && rule[idx+4] == ':' { | ||
| rulePart = rule[idx+5:] |
There was a problem hiding this comment.
I believe this is safe since all index offsets are in the string match with ".bzl", but just checking if you have tried this with unicode characters in the label to see if it might require rune based manipulation instead of char-index?
Buildtools PR checklist
Description
This PR extends edit label resolution to allow targeting .bzl files directly (for buildozer-style edits), e.g. //pkg:defs.bzl and //pkg:defs.bzl:rule. This makes it possible to apply edit transformations (like adding/removing entries from list attributes such as patches = [...]) to .bzl files, while still relying on buildifier-compatible formatting.
It also adds unit tests covering:
resolving .bzl targets via InterpretLabelForWorkspaceLocation
editing a patches list in a parsed .bzl file (add + remove) and validating formatted output
(optional) These changes were tested using the following steps
Run unit tests for the edited package:
go test ./edit
(Optional sanity) Run the specific new tests:
go test ./edit -run 'TestInterpretLabelForWorkspaceLocation_BzlFile|TestAddAndRemovePatchesInBzlFile'